```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Java线程池源码深度解析 | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
            background-color: #f9f9f9;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
            color: #222;
        }
        .hero {
            background: linear-gradient(135deg, #6e48aa 0%, #9d50bb 100%);
        }
        .code-block {
            background-color: #282c34;
            border-radius: 8px;
            color: #abb2bf;
        }
        .concept-card {
            transition: all 0.3s ease;
            border-left: 4px solid #6e48aa;
        }
        .concept-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 20px rgba(0,0,0,0.1);
        }
        .footer {
            background-color: #1a1a1a;
        }
        .highlight {
            background: linear-gradient(90deg, rgba(110,72,170,0.1) 0%, rgba(157,80,187,0.1) 100%);
            padding: 0.2em 0.4em;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero text-white py-20 md:py-32 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl text-center">
            <h1 class="text-4xl md:text-6xl font-bold mb-6">Java线程池源码深度解析</h1>
            <p class="text-xl md:text-2xl opacity-90 mb-8 max-w-3xl mx-auto">探索高效并发编程的核心机制与实现原理</p>
            <div class="flex justify-center space-x-4">
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full"><i class="fas fa-code mr-2"></i>并发编程</span>
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full"><i class="fas fa-cogs mr-2"></i>Java源码</span>
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full"><i class="fas fa-project-diagram mr-2"></i>设计模式</span>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl px-4 py-12">
        <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-12">
            <div class="p-8 md:p-12">
                <div class="flex items-center mb-6">
                    <div class="w-12 h-12 rounded-full bg-purple-100 flex items-center justify-center mr-4">
                        <i class="fas fa-terminal text-purple-600 text-xl"></i>
                    </div>
                    <div>
                        <h2 class="text-2xl font-bold">线程池的基本概念与作用</h2>
                        <p class="text-gray-500">高效管理线程生命周期和系统资源</p>
                    </div>
                </div>
                
                <div class="prose max-w-none">
                    <p class="text-lg mb-6">线程池是Java并发编程中非常重要的一个组件，它用于管理和复用线程，以减少创建和销毁线程的开销，并能够有效控制线程的数量，防止系统资源耗尽。线程池在大规模并发场景中尤为重要。</p>
                    
                    <div class="grid md:grid-cols-3 gap-6 mb-8">
                        <div class="concept-card bg-white p-6 rounded-lg shadow-md">
                            <div class="text-purple-600 text-2xl mb-3"><i class="fas fa-redo"></i></div>
                            <h3 class="font-bold text-lg mb-2">线程复用</h3>
                            <p class="text-gray-600">减少频繁创建和销毁线程的成本</p>
                        </div>
                        <div class="concept-card bg-white p-6 rounded-lg shadow-md">
                            <div class="text-purple-600 text-2xl mb-3"><i class="fas fa-tachometer-alt"></i></div>
                            <h3 class="font-bold text-lg mb-2">资源控制</h3>
                            <p class="text-gray-600">限制线程数量防止资源耗尽</p>
                        </div>
                        <div class="concept-card bg-white p-6 rounded-lg shadow-md">
                            <div class="text-purple-600 text-2xl mb-3"><i class="fas fa-tasks"></i></div>
                            <h3 class="font-bold text-lg mb-2">任务调度</h3>
                            <p class="text-gray-600">统一管理任务提交和执行</p>
                        </div>
                    </div>
                    
                    <h3 class="text-xl font-bold mt-8 mb-4">核心概念</h3>
                    <ul class="space-y-2 mb-6">
                        <li class="flex items-start">
                            <span class="text-purple-600 mr-2 mt-1"><i class="fas fa-dot-circle text-sm"></i></span>
                            <span><span class="font-medium highlight">核心线程数</span> (corePoolSize)：线程池中最小的线程数</span>
                        </li>
                        <li class="flex items-start">
                            <span class="text-purple-600 mr-2 mt-1"><i class="fas fa-dot-circle text-sm"></i></span>
                            <span><span class="font-medium highlight">最大线程数</span> (maximumPoolSize)：线程池中最大的线程数</span>
                        </li>
                        <li class="flex items-start">
                            <span class="text-purple-600 mr-2 mt-1"><i class="fas fa-dot-circle text-sm"></i></span>
                            <span><span class="font-medium highlight">空闲线程存活时间</span> (keepAliveTime)：非核心线程空闲时的存活时间</span>
                        </li>
                    </ul>
                    
                    <div class="mermaid mt-8 mb-10">
                        graph TD
                            A[任务提交] --> B{核心线程是否已满?}
                            B -- 否 --> C[创建新线程执行]
                            B -- 是 --> D{队列是否已满?}
                            D -- 否 --> E[任务入队等待]
                            D -- 是 --> F{最大线程是否已满?}
                            F -- 否 --> G[创建新线程执行]
                            F -- 是 --> H[执行拒绝策略]
                    </div>
                </div>
            </div>
        </div>

        <!-- ExecutorService Section -->
        <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-12">
            <div class="p-8 md:p-12">
                <div class="flex items-center mb-6">
                    <div class="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center mr-4">
                        <i class="fas fa-code-branch text-blue-600 text-xl"></i>
                    </div>
                    <div>
                        <h2 class="text-2xl font-bold">ExecutorService 接口概述</h2>
                        <p class="text-gray-500">任务执行管理的核心接口</p>
                    </div>
                </div>
                
                <div class="prose max-w-none">
                    <p><code>ExecutorService</code>是Java并发包中的一个重要接口，提供了管理任务执行的功能。它继承自<code>Executor</code>接口，并扩展了任务提交、任务终止、任务结果获取等功能。</p>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">public interface ExecutorService extends Executor {
    // 提交一个返回值的任务
    &lt;T&gt; Future&lt;T&gt; submit(Callable&lt;T&gt; task);
    
    // 关闭线程池
    void shutdown();
    
    // 尝试立即停止所有正在执行的任务
    List&lt;Runnable&gt; shutdownNow();
    
    // 等待线程池任务完成并返回结果
    List&lt;Runnable&gt; invokeAll(Collection&lt;? extends Callable&lt;T&gt;&gt; tasks) 
        throws InterruptedException;
}</code></pre>
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-6 mt-8">
                        <div class="bg-blue-50 p-6 rounded-lg">
                            <h3 class="font-bold text-lg mb-3 text-blue-800"><i class="fas fa-paper-plane mr-2"></i>submit()</h3>
                            <p>提交一个任务并返回<code>Future</code>对象，<code>Future</code>可以用来获取任务执行结果。</p>
                        </div>
                        <div class="bg-blue-50 p-6 rounded-lg">
                            <h3 class="font-bold text-lg mb-3 text-blue-800"><i class="fas fa-power-off mr-2"></i>shutdown()</h3>
                            <p>开始关闭线程池，线程池不再接收新的任务。</p>
                        </div>
                        <div class="bg-blue-50 p-6 rounded-lg">
                            <h3 class="font-bold text-lg mb-3 text-blue-800"><i class="fas fa-stop-circle mr-2"></i>shutdownNow()</h3>
                            <p>立即尝试停止所有正在执行的任务。</p>
                        </div>
                        <div class="bg-blue-50 p-6 rounded-lg">
                            <h3 class="font-bold text-lg mb-3 text-blue-800"><i class="fas fa-list-ol mr-2"></i>invokeAll()</h3>
                            <p>等待线程池任务完成并返回结果。</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- ThreadPoolExecutor Section -->
        <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-12">
            <div class="p-8 md:p-12">
                <div class="flex items-center mb-6">
                    <div class="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mr-4">
                        <i class="fas fa-server text-green-600 text-xl"></i>
                    </div>
                    <div>
                        <h2 class="text-2xl font-bold">ThreadPoolExecutor 类的实现</h2>
                        <p class="text-gray-500">线程池的核心实现类</p>
                    </div>
                </div>
                
                <div class="prose max-w-none">
                    <p><code>ThreadPoolExecutor</code>是线程池的核心实现类，它实现了<code>ExecutorService</code>接口，并提供了线程池的具体实现。<code>ThreadPoolExecutor</code>类通过维护核心线程池、最大线程池、任务队列等来调度和执行任务。</p>
                    
                    <h3 class="text-xl font-bold mt-8 mb-4">构造函数</h3>
                    <p><code>ThreadPoolExecutor</code>通过构造函数来初始化线程池的核心参数，如核心线程数、最大线程数、空闲线程存活时间等。</p>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">public class ThreadPoolExecutor implements ExecutorService {
    // 核心线程池大小
    private final int corePoolSize;
    // 最大线程池大小
    private final int maximumPoolSize;
    // 任务队列
    private final BlockingQueue&lt;Runnable&gt; workQueue;
    // 线程工厂
    private final ThreadFactory threadFactory;
    // 拒绝策略
    private final RejectedExecutionHandler handler;

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
            long keepAliveTime, TimeUnit unit,
            BlockingQueue&lt;Runnable&gt; workQueue,
            ThreadFactory threadFactory,
            RejectedExecutionHandler handler) {
        // 初始化线程池的各种参数
    }
}</code></pre>
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-4 mt-6 mb-8">
                        <div>
                            <h4 class="font-medium text-gray-700 mb-2">核心参数</h4>
                            <p><code>corePoolSize</code>、<code>maximumPoolSize</code>、<code>keepAliveTime</code>等决定了线程池的大小和任务调度的策略。</p>
                        </div>
                        <div>
                            <h4 class="font-medium text-gray-700 mb-2">任务队列</h4>
                            <p>任务提交到线程池后，会被放入任务队列中，等待空闲线程执行。</p>
                        </div>
                        <div>
                            <h4 class="font-medium text-gray-700 mb-2">线程工厂</h4>
                            <p>用于创建新线程的工厂类，默认使用<code>Executors.defaultThreadFactory()</code>。</p>
                        </div>
                        <div>
                            <h4 class="font-medium text-gray-700 mb-2">拒绝策略</h4>
                            <p>当线程池的任务队列满时，使用的策略。默认策略是<code>AbortPolicy</code>，会抛出<code>RejectedExecutionException</code>。</p>
                        </div>
                    </div>
                    
                    <h3 class="text-xl font-bold mt-8 mb-4">任务调度流程</h3>
                    <ol class="list-decimal pl-5 space-y-2 mb-6">
                        <li><span class="font-medium">任务提交</span>：当任务提交到线程池时，<code>ThreadPoolExecutor</code>会先判断当前线程池的线程数量。</li>
                        <li><span class="font-medium">任务入队</span>：如果当前线程池的核心线程数未达到<code>corePoolSize</code>，会直接创建新线程执行任务；如果线程池中的线程数已满，且任务队列未满，则将任务放入队列中等待执行。</li>
                        <li><span class="font-medium">创建新线程</span>：如果线程池的核心线程数已达到<code>corePoolSize</code>，且任务队列已满，那么线程池会尝试创建新的线程，直到达到<code>maximumPoolSize</code>。</li>
                        <li><span class="font-medium">拒绝策略</span>：如果线程池的线程数已达到<code>maximumPoolSize</code>，并且任务队列已满，线程池将执行预设的拒绝策略。</li>
                    </ol>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">public void execute(Runnable command) {
    if (command == null) throw new NullPointerException();
    // 尝试提交任务
    if (workerCountOf(ctl) &lt; corePoolSize) {
        if (addWorker(command, true)) return;
    }
    // 如果线程池未满，将任务放入队列
    if (workQueue.offer(command)) {
        if (workerCountOf(ctl) == 0) {
            addWorker(null, false);
        }
    }
    // 线程池满，拒绝策略
    else if (!addWorker(command, false))
        rejectedExecutionHandler.rejectedExecution(command, this);
}</code></pre>
                    </div>
                    
                    <div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 my-6">
                        <div class="flex">
                            <div class="flex-shrink-0 text-yellow-500">
                                <i class="fas fa-lightbulb"></i>
                            </div>
                            <div class="ml-3">
                                <p class="text-sm text-yellow-700">
                                    <span class="font-medium">任务提交流程</span>：首先检查线程池的核心线程数是否已满，若未满，则创建新线程；若线程池已满，则将任务放入任务队列中；如果任务队列已满，则执行拒绝策略。
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Work Thread Section -->
        <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-12">
            <div class="p-8 md:p-12">
                <div class="flex items-center mb-6">
                    <div class="w-12 h-12 rounded-full bg-orange-100 flex items-center justify-center mr-4">
                        <i class="fas fa-users-cog text-orange-600 text-xl"></i>
                    </div>
                    <div>
                        <h2 class="text-2xl font-bold">线程池的工作线程与任务执行</h2>
                        <p class="text-gray-500">理解线程池如何管理线程生命周期</p>
                    </div>
                </div>
                
                <div class="prose max-w-none">
                    <p>线程池的工作线程负责从任务队列中取出任务并执行。每个工作线程的生命周期由线程池管理，线程池会根据任务的数量和线程池的配置动态地增加或减少工作线程。</p>
                    
                    <h3 class="text-xl font-bold mt-8 mb-4">工作线程的创建与销毁</h3>
                    <p><code>ThreadPoolExecutor</code>根据核心线程数和最大线程数来管理工作线程。核心线程数以内的线程在空闲时不会被销毁，只有当线程池需要更多的线程时，才会创建新的工作线程。</p>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">// 创建工作线程
private boolean addWorker(Runnable firstTask, boolean core) {
    if (firstTask == null && core) throw new NullPointerException();
    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);
        // 判断线程池状态是否允许创建新线程
        if (rs >= SHUTDOWN) return false;
        // 创建工作线程
        if (workerCountOf(c) &lt; (core ? corePoolSize : maximumPoolSize)) {
            if (compareAndIncrementWorkerCount(c)) {
                Worker w = new Worker(firstTask);
                Thread t = w.thread;
                if (t != null) {
                    t.start();  // 启动工作线程
                }
                return true;
            }
        }
    }
}</code></pre>
                    </div>
                    
                    <p class="mt-4"><code>addWorker()</code>：该方法用于添加工作线程，如果线程池中已有足够的线程且工作线程未被销毁，则会新建线程并启动。</p>
                    
                    <h3 class="text-xl font-bold mt-8 mb-4">工作线程的执行流程</h3>
                    <p>当工作线程开始执行任务时，它会从任务队列中取出任务并执行。每个工作线程通过<code>runWorker()</code>方法循环获取任务并执行，直到线程池关闭或没有更多任务。</p>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    while (task != null || (task = getTask()) != null) {
        try {
            task.run();  // 执行任务
        } finally {
            task = null;
            w.completedTasks++;
            // 检查线程池状态，是否需要销毁该线程
        }
    }
}</code></pre>
                    </div>
                    
                    <p class="mt-4"><span class="font-medium">任务执行</span>：<code>runWorker()</code>方法不断从任务队列中取出任务并执行，直到任务队列为空或线程池关闭。</p>
                </div>
            </div>
        </div>

        <!-- Rejection Policy Section -->
        <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-12">
            <div class="p-8 md:p-12">
                <div class="flex items-center mb-6">
                    <div class="w-12 h-12 rounded-full bg-red-100 flex items-center justify-center mr-4">
                        <i class="fas fa-exclamation-triangle text-red-600 text-xl"></i>
                    </div>
                    <div>
                        <h2 class="text-2xl font-bold">线程池的拒绝策略</h2>
                        <p class="text-gray-500">处理无法执行的任务</p>
                    </div>
                </div>
                
                <div class="prose max-w-none">
                    <p>当线程池中的线程数已达到最大线程数且任务队列已满时，新的任务将会被拒绝执行。<code>ThreadPoolExecutor</code>提供了四种拒绝策略来处理这种情况：</p>
                    
                    <div class="grid md:grid-cols-2 gap-6 mt-8">
                        <div class="bg-red-50 p-6 rounded-lg border-l-4 border-red-500">
                            <h3 class="font-bold text-lg mb-3 text-red-800">AbortPolicy</h3>
                            <p>直接抛出异常<code>RejectedExecutionException</code>。</p>
                        </div>
                        <div class="bg-red-50 p-6 rounded-lg border-l-4 border-red-500">
                            <h3 class="font-bold text-lg mb-3 text-red-800">CallerRunsPolicy</h3>
                            <p>调用者线程执行该任务。</p>
                        </div>
                        <div class="bg-red-50 p-6 rounded-lg border-l-4 border-red-500">
                            <h3 class="font-bold text-lg mb-3 text-red-800">DiscardPolicy</h3>
                            <p>丢弃当前任务。</p>
                        </div>
                        <div class="bg-red-50 p-6 rounded-lg border-l-4 border-red-500">
                            <h3 class="font-bold text-lg mb-3 text-red-800">DiscardOldestPolicy</h3>
                            <p>丢弃任务队列中最旧的任务，然后尝试提交新的任务。</p>
                        </div>
                    </div>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">private void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    handler.rejectedExecution(r, e);
}</code></pre>
                    </div>
                    
                    <p><code>rejectedExecution()</code>：根据预设的拒绝策略来处理无法执行的任务。</p>
                </div>
            </div>
        </div>

        <!-- Shutdown Section -->
        <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-12">
            <div class="p-8 md:p-12">
                <div class="flex items-center mb-6">
                    <div class="w-12 h-12 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
                        <i class="fas fa-power-off text-indigo-600 text-xl"></i>
                    </div>
                    <div>
                        <h2 class="text-2xl font-bold">线程池的关闭与终止</h2>
                        <p class="text-gray-500">优雅地结束线程池运行</p>
                    </div>
                </div>
                
                <div class="prose max-w-none">
                    <p>线程池可以通过调用<code>shutdown()</code>或<code>shutdownNow()</code>来关闭。<code>shutdown()</code>会将线程池标记为不再接受新任务，并且会等待已提交任务执行完毕；而<code>shutdownNow()</code>会尝试停止所有正在执行的任务并返回待执行的任务。</p>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">public void shutdown() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        // 设置线程池为关闭状态
        advanceRunState(SHUTDOWN);
    } finally {
        mainLock.unlock();
    }
}</code></pre>
                    </div>
                    
                    <p><code>shutdown()</code>：线程池进入关闭状态，不再接受新任务，并等待当前任务完成。</p>
                </div>
            </div>
        </div>

        <!-- Monitoring Section -->
        <div class="bg-white rounded-xl shadow-lg overflow-hidden">
            <div class="p-8 md:p-12">
                <div class="flex items-center mb-6">
                    <div class="w-12 h-12 rounded-full bg-teal-100 flex items-center justify-center mr-4">
                        <i class="fas fa-chart-bar text-teal-600 text-xl"></i>
                    </div>
                    <div>
                        <h2 class="text-2xl font-bold">线程池的监控与管理</h2>
                        <p class="text-gray-500">实时了解线程池状态</p>
                    </div>
                </div>
                
                <div class="prose max-w-none">
                    <p>Java中的线程池提供了丰富的监控与管理功能，可以通过<code>ThreadPoolExecutor</code>中的方法查看当前线程池的状态、活跃线程数、队列中的任务数等信息。</p>
                    
                    <div class="code-block p-6 my-6 overflow-x-auto">
                        <pre><code class="language-java">public int getPoolSize() {
    return workerCountOf(ctl.get());
}</code></pre>
                    </div>
                    
                    <p><code>getPoolSize()</code>：获取当前线程池中的工作线程数。</p>
                    
                    <div class="mt-8 p-6 bg-teal-50 rounded-lg">
                        <h3 class="text-xl font-bold mb-4 text-teal-800">常用监控方法</h3>
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <span class="text-teal-600 mr-2 mt-1"><i class="fas fa-check-circle"></i></span>
                                <span><code>getActiveCount()</code> - 获取活跃线程数</span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-teal-600 mr-2 mt-1"><i class="fas fa-check-circle"></i></span>
                                <span><code>getCompletedTaskCount()</code> - 获取已完成任务数</span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-teal-600 mr-2 mt-1"><i class="fas fa-check-circle"></i></span>
                                <span><code>getQueue()</code> - 获取任务队列</span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-teal-600 mr-2 mt-1"><i class="fas fa-check-circle"></i></span>
                                <span><code>getLargestPoolSize()</code> - 获取线程池曾达到的最大线程数</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </main>

    <!-- Footer -->
    <footer class="footer text-white py-12 px-4">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-6 md:mb-0">
                    <h3 class="text-xl font-bold">技术小馆</h3>
                    <p class="text-gray-400 mt-2">探索技术奥秘，分享编程知识</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-gray-300 hover:text-white transition duration-300">
                        <i class="fas fa-globe mr-2"></i> http://www.yuque.com/jtostring
                    </a>
                </div>
            </div>
            <div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400">
                <p>© 2023 技术小馆. 保留所有权利.</p>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```